Q查询


  • 在 .filter() 等方法中默认都是使用了 'AND',如果想使用 'OR',那么就要使用 Q() 方法

  • 导入 Q() 方法

from django.db.models import  Q

  • & -> 'and'

# 查询 id >= 3 and id <=5 的数据

from app01.models import *
from django.db.models import Q

Student.objects.filter(Q(id__gte=3) & Q(id__lte=5))

# 等同于

Student.objects.filter(id__gte=3, id__lte=5)

  • | -> 'or'

# 查询 id >= 3 or id <=5 的数据

from app01.models import *
from django.db.models import Q

Student.objects.filter(Q(id__gte=3) | Q(id__lte=5))

  • ~ -> 非(取反)

# 查询 id != 3 的数据

from app01.models import *
from django.db.models import Q

Student.objects.filter(~Q(id=3))

# 等同于

Student.objects.exclude(id=3)

  • 混合使用

    • 注意: 如果是混合使用 Q() 查询一定要写在前面

# 查询 (id >= 3 or id <=5) and age = 25 的数据

from app01.models import *
from django.db.models import Q

Student.objects.filter(Q(id__gte=3) | Q(id__lte=5), age=25)

# 等同于

Student.objects.filter((Q(id__gte=3) | Q(id__lte=5)) & Q(age=25))

传递Q对象,构造查询条件


  • 使用场景: 
    • 当有多个Q查询的时候就使用该方法构建Q查询
    • 当使用Q查询的时候获取到的字段名是字符串类型的时候(xadmin中有多处使用该方法)

  • 使用该方法的时候最好查看一下它所生成的SQL语句是否与代码逻辑相符合

  • 传入条件进行查询

# 固定写法

from django.db.models import Q

q1 = Q()
q1.connector = 'OR/AND'  # 指定使用 OR 还是 AND,如果不指定默认使用 AND
q1.children.append(('字段名', '参数'))
q1.children.append(('字段名__条件', '参数'))
……

变量名 = 表的类.objects.filter(q1)

from django.db.models import Q

q1 = Q()
q1.connector = 'OR'  # 指定使用 OR 还是 AND,如果不指定默认使用 AND
q1.children.append(('id', 1))
q1.children.append(('id', 2))
q1.children.append(('price__gte', 3))

book = Book.objects.filter(q1)

print(book.query)  # SELECT id, title, price, publish_id FROM app01_book WHERE (id = 1 OR id = 2 OR id = 3)

  • 合并条件进行查询

# 固定写法

from django.db.models import Q

con = Q()

q1 = Q()
q1.connector = 'OR/AND'  # 指定使用 OR 还是 AND,如果不指定默认使用 AND
q1.children.append(('字段名', '参数'))
q1.children.append(('字段名__条件', '参数'))
……

q2 = Q()
q2.connector = 'OR/AND'  # 指定使用 OR 还是 AND,如果不指定默认使用 AND
q2.children.append(('字段名', '参数'))
q2.children.append(('字段名__条件', '参数'))
……

con.add(q1, 'OR/AND')
con.add(q2, 'OR/AND')
……

变量名 = 表的类.objects.filter(con)

# 查询 (id=1 并且 title=红楼梦 并且 price>=50) 或者 (price=100 并且 title=三国演义 并且 price>=50) 的书籍

from django.db.models import Q

con = Q()

q1 = Q()
q1.children.append(('id', 1))
q1.children.append(('title', '红楼梦'))
q1.children.append(('price__gte', 50))

q2 = Q()
q2.children.append(('price', 100))
q2.children.append(('title', '三国演义'))
q2.children.append(('price__gte', 50))

con.add(q1, 'OR')
con.add(q2, 'OR')

book = Book.objects.filter(con)

print(book.query)  # SELECT id, title, price, publish_id FROM app01_book WHERE ((id = 1 AND title = 红楼梦) OR (price = 100 AND title = 三国演义))

# 查询 (id=1 或者 title=红楼梦 或者 price>=50) 并且 (price=100 或者 title=三国演义 或者 price>=50) 的数据

from django.db.models import Q

con = Q()

q1 = Q()
q1.connector = 'OR'  # 指定使用 OR 还是 AND,如果不指定默认使用 AND
q1.children.append(('id', 1))
q1.children.append(('title', '红楼梦'))
q1.children.append(('price__gte', 50))

q2 = Q()
q2.connector = 'OR'  # 指定使用 OR 还是 AND,如果不指定默认使用 AND
q2.children.append(('price', 100))
q2.children.append(('title', '三国演义'))
q2.children.append(('price__gte', 50))

con.add(q1, 'AND')
con.add(q2, 'AND')

book = Book.objects.filter(con)

print(book.query)  # SELECT id, title, price, publish_id FROM app01_book WHERE ((id = 1 OR title = 红楼梦) AND (price = 100 OR title = 三国演义))